from django import template
from django.conf import settings

register = template.Library()

class TranslateNode(template.Node):
    def __init__(self, from_var, to_var = None, lang = None, lang_var = None):
        self.from_var = from_var
        self.to_var   = to_var
        self.lang     = lang
        self.lang_var = lang_var

    def render(self, context):
        lang = None

        try:
            from_text = template.resolve_variable(self.from_var, context)
        except template.VariableDoesNotExist:
            return ''

        if not hasattr(from_text, 'render'):
            # the default is just to return whatever we have,
            # similar to the failure mode of {% trans ... %}
            return str(from_text)


        # laboriously find the value of `lang'
        
        if self.lang_var:
            try:
                lang = template.resolve_variable(self.lang_var, context)
            except template.VariableDoesNotExist:
                lang = None
        elif self.lang:
            lang = self.lang

        if self.lang:
            languages = [(k, v) for k, v in settings.LANGUAGES
                         if k in self.lang                      ]
            if len(languages) == 0:
                try:
                    lang = context['LANGUAGE_CODE']
                except KeyError:
                    lang = settings.LANGUAGE
            else:
                exact_languages = [(k, v) for k, v in languages
                                   if k == self.lang                     ]
                if len(exact_languages) == 0:
                    lang = languages[0][0]
                else:
                    lang = exact_languages[0][0]
        else:
             try:
                 lang = context['LANGUAGE_CODE']
             except KeyError:
                 lang = settings.LANGUAGE
                    
                

        trans_text = from_text.render(lang)

        if self.to_var:
     
            context[self.to_var] = trans_text
            return ''
        else:
        
            return trans_text
            

def dynamic_translate(parser, token):
    """
    Choose a particular language for a particular InternationalText.

    Examples::

    -Use current language:
         {% transdyn module.description %} 

    -Use current language, but instead of outputting it, put it into a context:
         {% transdyn module.description as translated_text %}
         {{ translated_text|wikiparse }}

    -Use another language:
         {% transdyn module.description LANGUAGE %}
         {% transdyn module.description "es" %}
         ...
         
    """
    argv = list(token.split_contents())

    tagname = argv[0]
    
    if len(argv) not in [2, 3, 4, 5]:
        raise template.TemplateSyntaxError, "%s not given correct arguments." %\
              tagname

    from_var = argv[1]

    if from_var[0] == '"' or from_var[-1] == '"':
        raise template.TemplateSyntaxError, "%s needs a context variable for the first argument." % tagname

    # deal with each argument case
    ###################

    
    # {% dyntrans foo.text %}
    if   len(argv) == 2:
        return TranslateNode(from_var = from_var)

    # {% dyntrans foo.text "en" %} or
    # {% dyntrans foo.text LANGUAGE %}
    elif len(argv) == 3:
        to_lang = argv[2]
        if to_lang[0] == to_lang[-1] and to_lang[0] == '"':
            # We recieved a string value for the language
            return TranslateNode(from_var = from_var, lang = to_lang[1:-1])
        else:
            # We recieved a to-be-resolved variable name
            return TranslateNode(from_var = from_var, lang_var = to_lang)

    # {% dyntrans foo.text as newvar %}
    elif len(argv) == 4:
        if argv[2].upper() != 'AS':
            raise template.TemplateSyntaxError, "%s not given correct arguments." % tagname
        to_var = argv[3]
        if to_var[0] == '"' or to_var[-1] == '"':
            raise template.TemplateSyntaxError, "%s not given correct arguments." % tagname
        return TranslateNode(from_var = from_var, to_var = to_var)

    # {% dyntrans foo.text as newvar "es" %} or
    # {% dyntrans foo.text as newvar LANGUAGE %}
    elif len(argv) == 5:
        if argv[2].upper() != 'AS':
            raise template.TemplateSyntaxError, "%s not given correct arguments." % tagname
        to_var = argv[3]
        if to_var[0] == '"' or to_var[-1] == '"':
            raise template.TemplateSyntaxError, "%s not given correct arguments." % tagname
        to_lang = argv[4]
        if to_lang[0] == to_lang[-1] and to_lang[0] == '"':
            # We recieved a string value for the language
            return TranslateNode(from_var = from_var,
                                 to_var   = to_var,
                                 lang     = to_lang[1:-1])
        else:
            # We recieved a to-be-resolved variable name
            return TranslateNode(from_var = from_var,
                                 to_var   = to_var,
                                 lang_var = to_lang)


register.tag('transdyn', dynamic_translate)
